package com.lhz.project.system.service.dept.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.lhz.common.constant.DataStatusEnum;
import com.lhz.common.page.BaseQueryParam;
import com.lhz.common.page.NewPageBean;
import com.lhz.framework.aspect.param.DataScope;
import com.lhz.framework.security.HolderInfoManager;
import com.lhz.project.system.mapper.dept.DeptMapper;
import com.lhz.project.system.model.entity.dept.Dept;
import com.lhz.project.system.model.param.dept.DeptParam;
import com.lhz.project.system.model.vo.dept.DeptTreeVo;
import com.lhz.project.system.service.dept.DeptService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author LiHuaZhi
 * @since 2020-06-14 14:24:22
 */
@Service

public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {
    @Resource
    private DeptMapper deptMapper;


    @Override
    public Dept selectByPrimaryKey(Integer id) {
        return deptMapper.selectByPrimaryKey(id);
    }

    @Override
    @DataScope(deptAlias = "a")
    public NewPageBean<Dept> listDept(BaseQueryParam param) {
        PageHelper.startPage(1, 3);
        return NewPageBean.generatePage(() -> deptMapper.listDept(param), param, Dept.class);
    }

    /**
     * 树形部门
     *
     * @return
     */
    @Override
    @DataScope(deptAlias = "a")
    public List<DeptTreeVo> treeDept() {
        //查询列表
        BaseQueryParam param = new BaseQueryParam();
        List<DeptTreeVo> deptList = deptMapper.listTreeDept(param);
        return buildDeptTree(deptList);
    }

    @Override
    public int insert(DeptParam param) {
        String userId = HolderInfoManager.getUserId();
        Dept dept = new Dept();
        BeanUtils.copyProperties(param, dept);

        dept.setStatus(DataStatusEnum.VALID.getCode());
        dept.setDelFlag(DataStatusEnum.VALID.getCode());
        dept.setCreateBy(userId);
        dept.setUpdateBy(userId);
        return deptMapper.insert(dept);
    }

    @Override
    public int updateByPrimaryKey(DeptParam param) {
        String userId = HolderInfoManager.getUserId();
        Dept dept = new Dept();
        BeanUtils.copyProperties(param, dept);

        dept.setUpdateBy(userId);
        return deptMapper.updateById(dept);
    }

    @Override
    public int deletePhyByPrimaryKey(Integer id) {
        return deptMapper.deletePhyByPrimaryKey(id);
    }

    @Override
    public int deletePhyByPrimaryKeys(List<Integer> ids) {
        return deptMapper.deletePhyByPrimaryKeys(ids);
    }

    /**
     * 构建前端所需要树结构
     *
     * @param deptList 部门列表
     * @return 树结构列表
     */
    private List<DeptTreeVo> buildDeptTree(List<DeptTreeVo> deptList) {
        //新集合
        List<DeptTreeVo> returnList = new ArrayList<>();

        List<Integer> tempList = new ArrayList<>();
        for (DeptTreeVo dept : deptList) {
            tempList.add(dept.getId());
        }
        for (DeptTreeVo dept : deptList) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(deptList, dept);
                returnList.add(dept);
            }
        }
        //没有查询到节点则以当前节点
        if (returnList.isEmpty()) {
            returnList = deptList;
        }
        return returnList;
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<DeptTreeVo> list, DeptTreeVo t) {
        // 得到子节点列表
        List<DeptTreeVo> childList = getChildList(list, t);
        t.setChildren(childList);
        for (DeptTreeVo tChild : childList) {
            // 判断是否有子节点
            if (Objects.isNull(tChild.getParentId()) && tChild.getParentId().equals(t.getId())) {
                for (DeptTreeVo n : childList) {
                    recursionFn(list, n);
                }
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<DeptTreeVo> getChildList(List<DeptTreeVo> list, DeptTreeVo t) {
        List<DeptTreeVo> tList = new ArrayList<>();
        for (DeptTreeVo n : list) {
            if (Objects.nonNull(n.getParentId()) && n.getParentId().equals(t.getId())) {
                tList.add(n);
            }
        }
        return tList;
    }
}